Integrate objects
* Use all features so can pass object to P3
Assign Cell cycle scores * Can compare assignment to individual run assignments
Run SCTransform on individual objects
* regress - Cell cycle + noregress + regress.CC - regress on cell cycle - probably not the best option as it removes any cell cycle information that may be important for differentiating cells + regress.diff - regress on the difference in cell cycle values; per Seurat notations, it preserves cell cycle information relevant to development * regress - other features + nCounts_RNA + percent.mt
Cluster & Plot!
Save each object to a separate file
importDate - select the creation date for the desired object
Set up libraries and directories
Plot Counts Comparisons


Normalize & Scale
Use SCTransform with regression options noted Calculate pca and umap
Preserve all features for Precepts compatibility
Optionally Plot Missing Features
Note that features present in <= 4 cells do not make it through SCTransform
Cluster the individual runs
Note: Ran individual PCA/UMAP on a subset of genes in 1a.
Run here on all genes? Not sure that this will substantially change anything.
Preliminary Cluster ID
Integrate the objects
Preserve as many features as possible in the integrated object
Optionally Plot Missing Features
Lose ~2500 features (of 16990) during integration
Plot UMAP and PCA
15:02:27 UMAP embedding parameters a = 0.9922 b = 1.112
15:02:27 Read 1657 rows and found 30 numeric columns
15:02:27 Using Annoy for neighbor search, n_neighbors = 30
15:02:27 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:02:28 Writing NN index file to temp file /var/folders/qm/j2npc7ss1bv_6ks_fh41llp0yk4_ps/T//RtmpguGud9/file1601f4df52f40
15:02:28 Searching Annoy index using 1 thread, search_k = 3000
15:02:28 Annoy recall = 100%
15:02:28 Commencing smooth kNN distance calibration using 1 thread
15:02:29 Initializing from normalized Laplacian + noise
15:02:29 Commencing optimization for 500 epochs, with 66338 positive edges
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:02:32 Optimization finished
15:04:39 UMAP embedding parameters a = 0.9922 b = 1.112
15:04:39 Read 2754 rows and found 30 numeric columns
15:04:39 Using Annoy for neighbor search, n_neighbors = 30
15:04:39 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:04:39 Writing NN index file to temp file /var/folders/qm/j2npc7ss1bv_6ks_fh41llp0yk4_ps/T//RtmpguGud9/file1601f1bf13abc
15:04:39 Searching Annoy index using 1 thread, search_k = 3000
15:04:40 Annoy recall = 100%
15:04:40 Commencing smooth kNN distance calibration using 1 thread
15:04:41 Initializing from normalized Laplacian + noise
15:04:41 Commencing optimization for 500 epochs, with 113294 positive edges
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:04:47 Optimization finished
15:07:51 UMAP embedding parameters a = 0.9922 b = 1.112
15:07:51 Read 3404 rows and found 30 numeric columns
15:07:51 Using Annoy for neighbor search, n_neighbors = 30
15:07:51 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:07:51 Writing NN index file to temp file /var/folders/qm/j2npc7ss1bv_6ks_fh41llp0yk4_ps/T//RtmpguGud9/file1601f7a471af8
15:07:51 Searching Annoy index using 1 thread, search_k = 3000
15:07:52 Annoy recall = 100%
15:07:53 Commencing smooth kNN distance calibration using 1 thread
15:07:54 Initializing from normalized Laplacian + noise
15:07:54 Commencing optimization for 500 epochs, with 140766 positive edges
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:08:00 Optimization finished
15:09:42 UMAP embedding parameters a = 0.9922 b = 1.112
15:09:42 Read 1873 rows and found 30 numeric columns
15:09:42 Using Annoy for neighbor search, n_neighbors = 30
15:09:42 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:09:43 Writing NN index file to temp file /var/folders/qm/j2npc7ss1bv_6ks_fh41llp0yk4_ps/T//RtmpguGud9/file1601f523bce7f
15:09:43 Searching Annoy index using 1 thread, search_k = 3000
15:09:44 Annoy recall = 100%
15:09:44 Commencing smooth kNN distance calibration using 1 thread
15:09:45 Initializing from normalized Laplacian + noise
15:09:45 Commencing optimization for 500 epochs, with 76218 positive edges
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
15:09:49 Optimization finished
Save the data





Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 1657
Number of edges: 69751
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7643
Number of communities: 8
Elapsed time: 0 seconds
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|



Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 2754
Number of edges: 113800
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7809
Number of communities: 10
Elapsed time: 0 seconds
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|



Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 3404
Number of edges: 139696
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7827
Number of communities: 11
Elapsed time: 0 seconds
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|



Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
Number of nodes: 1873
Number of edges: 91025
Running Louvain algorithm...
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7090
Number of communities: 9
Elapsed time: 0 seconds
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|


Error: Cannot find 'pca' in this Seurat object
LS0tCnRpdGxlOiAiQU1MLUVUTyBTTyAtIGludGVncmF0ZSwgc2N0LCBjbHVzdGVyIgphdXRob3I6ICJUTHVzYXJkaSIKZGF0ZTogIjExLzA1LzIwMjAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKcGFyYW1zOgogIGxvY2FsOiBUUlVFCi0tLQoKSW50ZWdyYXRlIG9iamVjdHMgICAKKiBVc2UgYWxsIGZlYXR1cmVzIHNvIGNhbiBwYXNzIG9iamVjdCB0byBQMwoKQXNzaWduIENlbGwgY3ljbGUgc2NvcmVzCiogQ2FuIGNvbXBhcmUgYXNzaWdubWVudCB0byBpbmRpdmlkdWFsIHJ1biBhc3NpZ25tZW50cwoKUnVuIFNDVHJhbnNmb3JtIG9uIGluZGl2aWR1YWwgb2JqZWN0cyAgIAoqIHJlZ3Jlc3MgLSBDZWxsIGN5Y2xlCiAgKyBub3JlZ3Jlc3MKICArIHJlZ3Jlc3MuQ0MgLSByZWdyZXNzIG9uIGNlbGwgY3ljbGUgLSBwcm9iYWJseSBub3QgdGhlIGJlc3Qgb3B0aW9uIGFzIGl0IHJlbW92ZXMgYW55IGNlbGwgY3ljbGUgaW5mb3JtYXRpb24gdGhhdCBtYXkgYmUgaW1wb3J0YW50IGZvciBkaWZmZXJlbnRpYXRpbmcgY2VsbHMKICArIHJlZ3Jlc3MuZGlmZiAtIHJlZ3Jlc3Mgb24gdGhlIGRpZmZlcmVuY2UgaW4gY2VsbCBjeWNsZSB2YWx1ZXM7IHBlciBTZXVyYXQgbm90YXRpb25zLCBpdCBwcmVzZXJ2ZXMgY2VsbCBjeWNsZSBpbmZvcm1hdGlvbiByZWxldmFudCB0byBkZXZlbG9wbWVudAoqIHJlZ3Jlc3MgLSBvdGhlciBmZWF0dXJlcwogICsgbkNvdW50c19STkEgKyBwZXJjZW50Lm10CiAgCkNsdXN0ZXIgJiBQbG90IQoKU2F2ZSBlYWNoIG9iamVjdCB0byBhIHNlcGFyYXRlIGZpbGUKCmltcG9ydERhdGUgLSBzZWxlY3QgdGhlIGNyZWF0aW9uIGRhdGUgZm9yIHRoZSBkZXNpcmVkIG9iamVjdAogIAojIyMgU2V0IHVwIGxpYnJhcmllcyBhbmQgZGlyZWN0b3JpZXMKCmBgYHtyICJzZXR1cF9saWJzIiwgaW5jbHVkZT1GQUxTRX0KI2tuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KG5ldHdvcmtEMykKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZHBseXIpCgpydW5zMnByb2Nlc3MgPSBjKCJkbXNvIiwgImF2YSIsICJvcnkiLCAiY29tYm8iKQpiYXNlbGluZSA9ICJkbXNvIgppbXBvcnREYXRlIDwtICIyMDIxLTAxLTA1IgpgYGAKCmBgYHtyICJzZXR1cF92YXJzIiwgaW5jbHVkZT1GQUxTRX0KZGlyZWN0b3J5ID0gbGlzdChyYXcgPSAiL1VzZXJzL2x1c2FyZGkvRG9jdW1lbnRzL0NFREFSL1Byb2plY3RzLzMuQVNYTF9tdXRhbnQvMS5BTUxfRVRPL2FuYWx5c2lzL2RhdGEvcmF3IiwKICAgICAgICAgICAgICAgICByZGEgPSAiL1VzZXJzL2x1c2FyZGkvRG9jdW1lbnRzL0NFREFSL1Byb2plY3RzLzMuQVNYTF9tdXRhbnQvMS5BTUxfRVRPL2FuYWx5c2lzL2RhdGEvcmRhIikKCmV4cHRzLmxzIDwtIHJlYWRSRFMoc3ByaW50ZigiJXMvYW1sX2V0by5wcmVwcm9jU08ubm9maWx0LiVzLnJkcyIsIGRpcmVjdG9yeSRyZGEsIGltcG9ydERhdGUpKQpgYGAKCiMjIyBQbG90IENvdW50cyBDb21wYXJpc29ucwoKYGBge3IsIGVjaG89RkFMU0V9CnBsb3RTZXQgPSBsaXN0KGRtc28gPSBsaXN0KGNvbCA9ICIjZTQxYTFjIiwgbHR5ID0gMSksCiAgICAgICAgICAgICAgIGF2YSA9IGxpc3QoY29sID0gIiMzNzdlYjgiLCBsdHkgPSAxKSwKICAgICAgICAgICAgICAgb3J5ID0gbGlzdChjb2wgPSAiIzRkYWY0YSIsIGx0eSA9IDEpLAogICAgICAgICAgICAgICBjb21ibyA9IGxpc3QoY29sID0gIiNhZGFmNGEiLCBsdHkgPSAxKSkKcnVucyA8LSBuYW1lcyhleHB0cy5scykKCnBsb3RGZWF0dXJlcyA8LSBjKCJuQ291bnRfUk5BIiwgIm5GZWF0dXJlX1JOQSIpCmZvciAobXlmZWF0dXJlIGluIHBsb3RGZWF0dXJlcykgewogICMgU2V0IHVwIERlbnNpdHkgUGxvdAogIG1heERlbnMgPC0gMAogIG1heEN0cyA8LSAwCiAgZm9yIChteXJ1biBpbiBuYW1lcyhleHB0cy5scykpIHsKICAgIG15ZGVucyA8LSBkZW5zaXR5KGV4cHRzLmxzW1tteXJ1bl1dQG1ldGEuZGF0YVtbbXlmZWF0dXJlXV0pCiAgICBtYXhEZW5zIDwtIG1heChtYXhEZW5zLCBteWRlbnMkeSkKICAgIG1heFBjdCA8LSAxCiAgICBtYXhDdHMgPC0gbWF4KG1heEN0cywgZXhwdHMubHNbW215cnVuXV1AbWV0YS5kYXRhW1tteWZlYXR1cmVdXSkKICB9CgogICMgQ3JlYXRlIGEgcGxvdCBwYW5lCiAgcGxvdChOVUxMLCB4bGltPWMoMCwgbWF4Q3RzKSwgeWxpbSA9IGMoMCwgbWF4RGVucyksIAogICAgICAgeGxhYiA9IHNwcmludGYoIiVzIiwgbXlmZWF0dXJlKSwKICAgICAgIHlsYWIgPSAiRGVuc2l0eSIsIGxhcyA9IDEsCiAgICAgICBtYWluID0gc3ByaW50ZigiRGlzdHJpYnV0aW9uIG9mICVzIHBlciBDZWxsIGJ5IEV4cGVyaW1lbnQiLCBteWZlYXR1cmUpKQogIGFibGluZShoID0gMCwgY29sID0gImdyZXk4MCIpCgogICMgQWRkIGEgbGVnZW5kCiAgbGVnZW5kKHg9InRvcHJpZ2h0IiwgbGVnZW5kID0gcnVucywgbHdkID0gMiwKICAgICAgICAgY29sID0gdW5saXN0KHBsb3RTZXQpW3Bhc3RlKHJ1bnMsICJjb2wiLCBzZXAgPSAiLiIpXSwKICAgICAgICAgbHR5ID0gYXMubnVtZXJpYyh1bmxpc3QocGxvdFNldClbcGFzdGUocnVucywgImx0eSIsIHNlcCA9ICIuIildKSkKCiAgIyBQbG90IGVhY2ggZGVuc2l0eSBsaW5lCiAgZm9yIChteXJ1biBpbiBuYW1lcyhleHB0cy5scykpIHsKICAgIGxpbmVzKGRlbnNpdHkoZXhwdHMubHNbW215cnVuXV1AbWV0YS5kYXRhW1tteWZlYXR1cmVdXSksIGNvbCA9IHBsb3RTZXRbW215cnVuXV0kY29sLAogICAgICAgICAgbHdkID0gMikKICB9Cn0KYGBgCgojIyMgTm9ybWFsaXplICYgU2NhbGUKVXNlIFNDVHJhbnNmb3JtIHdpdGggcmVncmVzc2lvbiBvcHRpb25zIG5vdGVkCkNhbGN1bGF0ZSBwY2EgYW5kIHVtYXAgCgpQcmVzZXJ2ZSBhbGwgZmVhdHVyZXMgZm9yIFByZWNlcHRzIGNvbXBhdGliaWxpdHkKCmBgYHtyLCAicnVuU0NUIiwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KcmVncmVzc2lvbnMgPC0gbGlzdChub3JlZ3Jlc3Npb24gPSAiTlVMTCIsCiAgICAgICAgICAgICAgICAgICAgcmVncmVzcy5DQyA9IGMoIlMuU2NvcmUiLCAiRzJNLlNjb3JlIiksCiAgICAgICAgICAgICAgICAgICAgcmVncmVzcy5EaWZmID0gYygiQ0MuRGlmZmVyZW5jZSIpKSAgICAKcmVncmVzc2lvbjJ1c2UgPC0gInJlZ3Jlc3MuRGlmZiIKCmZvciAobXlyZWdyZXNzIGluIHJlZ3Jlc3Npb24ydXNlKSB7CiAgZm9yIChteXJ1biBpbiBuYW1lcyhleHB0cy5scykpIHsKICAgIG15c28gPC0gZXhwdHMubHNbW215cnVuXV0KICAgIGlmIChteXJlZ3Jlc3MgPT0gIm5vcmVncmVzc2lvbiIpIHsKICAgICAgbXlhc3NheSA8LSAiU0NUIgogICAgICBteXNvIDwtIFNDVHJhbnNmb3JtKG15c28sIHZlcmJvc2UgPSBGQUxTRSwgbmV3LmFzc2F5Lm5hbWUgPSBteWFzc2F5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUuZmVhdHVyZXMubiA9IG5yb3cobXlzb0Bhc3NheXMkUk5BQGNvdW50cykpCiAgICB9IGVsc2UgewogICAgICBteWFzc2F5IDwtIGdzdWIoInJlZ3Jlc3MiLCAiU0NUIiwgbXlyZWdyZXNzKQogICAgICBteXNvIDwtIFNDVHJhbnNmb3JtKG15c28sIHZlcmJvc2UgPSBGQUxTRSwgbmV3LmFzc2F5Lm5hbWUgPSBteWFzc2F5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFycy50by5yZWdyZXNzID0gcmVncmVzc2lvbnNbW215cmVncmVzc11dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUuZmVhdHVyZXMubiA9IG5yb3cobXlzb0Bhc3NheXMkUk5BQGNvdW50cykpCiAgICB9CiAgICAKICAgICMgQ2FsY3VsYXRlIHBjYQogICAgbXlwY2EgPC0gZ3N1YigiU0NUIiwgInBjYSIsIG15YXNzYXkpCiAgICBteXBjYWtleSA8LSBwYXN0ZShnc3ViKCIvLiIsICIiLCBteXBjYSksICJfIiwgc2VwID0gIiIpCiAgICBteXNvIDwtIFJ1blBDQShteXNvLCB2ZXJib3NlID0gRkFMU0UsIGFzc2F5ID0gbXlhc3NheSwKICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uLm5hbWUgPSBteXBjYSwgcmVkdWN0aW9uLmtleSA9IG15cGNha2V5KQogICAgICAKICAgICMgQ3JlYXRlIHVtYXAKICAgIG15dW1hcCA8LSBnc3ViKCJwY2EiLCAidW1hcCIsIG15cGNhKQogICAgbXl1bWFwa2V5IDwtIHBhc3RlKGdzdWIoIi8uIiwgIiIsIG15dW1hcCksICJfIiwgc2VwID0gIiIpCiAgICBteXNvIDwtIFJ1blVNQVAobXlzbywgZGltcyA9IDE6MzAsIGFzc2F5ID0gbXlhc3NheSwKICAgICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9IG15cGNhLCByZWR1Y3Rpb24ubmFtZSA9IG15dW1hcCwgcmVkdWN0aW9uLmtleSA9IG15dW1hcGtleSkKICAgIAogICAgZXhwdHMubHNbW215cnVuXV0gPC0gbXlzbwogIH0gCn0KYGBgCgojIyMgT3B0aW9uYWxseSBQbG90IE1pc3NpbmcgRmVhdHVyZXMKTm90ZSB0aGF0IGZlYXR1cmVzIHByZXNlbnQgaW4gPD0gNCBjZWxscyBkbyBub3QgbWFrZSBpdCB0aHJvdWdoIFNDVHJhbnNmb3JtCgpgYGB7ciwgInBsb3RtaXNzaW5nZmVhdCIsZWNobz1GQUxTRX0KaWYgKFRSVUUpIHsKICBmb3IgKG15cnVuIGluIG5hbWVzKGV4cHRzLmxzKSkgewogICAgbXlzbyA8LSBleHB0cy5sc1tbbXlydW5dXQogICAgbG9zdEZlYXQgPC0gcm93bmFtZXMobXlzb0Bhc3NheXMkUk5BQGNvdW50cylbIShyb3duYW1lcyhteXNvQGFzc2F5cyRSTkFAY291bnRzKSAlaW4lIHJvd25hbWVzKG15c29AYXNzYXlzJFNDVC5EaWZmQGNvdW50cykpXQogICAgY291bnRzLnBlci5mZWF0IDwtIGFwcGx5KG15c29AYXNzYXlzJFJOQUBjb3VudHMsIDEsIHN1bSkKICAgIGNlbGxzLnBlci5mZWF0IDwtIE1hdHJpeDo6cm93U3VtcyhteXNvQGFzc2F5cyRSTkFAY291bnRzID4gMCkKICAgIAogICAgIyBQbG90IGNvdW50cyBhbmQgY2VsbHMgCiAgICBwbG90KHggPSBsb2cyKGNvdW50cy5wZXIuZmVhdCksIHkgPSBsb2cyKGNlbGxzLnBlci5mZWF0KSwgcGNoID0gMjAsIGNleCA9IDAuNSkKICAgIHBvaW50cyh4ID0gbG9nMihjb3VudHMucGVyLmZlYXRbbG9zdEZlYXRdKSwgeSA9IGxvZzIoY2VsbHMucGVyLmZlYXRbbG9zdEZlYXRdKSwgcGNoID0gMjAsIGNleCA9IDAuNSwgY29sID0gInJlZCIpCiAgfQp9CmBgYAoKIyMjIENsdXN0ZXIgdGhlIGluZGl2aWR1YWwgcnVucwpOb3RlOiBSYW4gaW5kaXZpZHVhbCBQQ0EvVU1BUCBvbiBhIHN1YnNldCBvZiBnZW5lcyBpbiAxYS4gICAgClJ1biBoZXJlIG9uIGFsbCBnZW5lcz8gTm90IHN1cmUgdGhhdCB0aGlzIHdpbGwgc3Vic3RhbnRpYWxseSBjaGFuZ2UgYW55dGhpbmcuCgpgYGB7ciwgImlDbHVzdGVyIiwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZm9yIChteXJ1biBpbiBuYW1lcyhleHB0cy5scykpIHsKICBteXNvIDwtIGV4cHRzLmxzW1tteXJ1bl1dCiAgCiAgZm9yIChteXJlZ3Jlc3MgaW4gcmVncmVzc2lvbjJ1c2UpIHsKICAgIG15YXNzYXkgPC0gZ3N1YigicmVncmVzcyIsICJTQ1QiLCBteXJlZ3Jlc3MpCiAgICBteXBjYSA8LSBnc3ViKCJyZWdyZXNzIiwgInBjYS5TQ1QiLCBteXJlZ3Jlc3MpCiAgICBteXBjYV9rZXkgPC0gZ3N1YigicmVncmVzcyIsICJwY2FTQ1RfIiwgbXlyZWdyZXNzKQogICAgbXlmZWF0dXJlcyA8LSByb3duYW1lcyhteXNvQGFzc2F5c1tbbXlhc3NheV1dKQogICAgbXl1bWFwIDwtIGdzdWIoInBjYSIsICJ1bWFwIiwgbXlwY2EpCiAgICAKICAgICMgUGVyZm9ybSBQQ0Egb24gYWxsIGZlYXR1cmVzIChub3RlIHRoYXQgbm9uLXZhcmlhYmxlIGZlYXR1cmVzIHdpbGwgYmUgZHJvcHBlZCkKICAgIG15c28gPC0gUnVuUENBKG15c28sIGFzc2F5ID0gbXlhc3NheSwgZmVhdHVyZXMgPSBteWZlYXR1cmVzLAogICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uLm5hbWUgPSBteXBjYSwgcmVkdWN0aW9uLmtleSA9IG15cGNhX2tleSkKICAgIAogICAgbXlwbG90IDwtIEVsYm93UGxvdChteXNvLCByZWR1Y3Rpb24gPSBteXBjYSwgbmRpbXMgPSA1MCkKICAgIHBsb3QobXlwbG90ICsgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gbXlydW4sIHN1YnRpdGxlID0gbXlyZWdyZXNzKSkKICAgIERpbUhlYXRtYXAobXlzbywgcmVkdWN0aW9uID0gbXlwY2EsIGRpbXMgPSAxOjE1LCBjZWxscyA9IDUwMCwgYmFsYW5jZWQgPSBUUlVFKQogIAogICAgbXlzbyA8LSBGaW5kTmVpZ2hib3JzKG15c28sIGRpbXMgPSAxOjUwLCBhc3NheSA9IG15YXNzYXksIHJlZHVjdGlvbiA9IG15cGNhKQogICAgbXlncmFwaCA8LSBwYXN0ZShteWFzc2F5LCAic25uIiwgc2VwID0gIl8iKQogICAgbXlzbyA8LSBGaW5kQ2x1c3RlcnMobXlzbywgZ3JhcGgubmFtZSA9IG15Z3JhcGgsIHJlc29sdXRpb24gPSAwLjgpCiAgICAKICAgICMgQ3JlYXRlIFVNQVAKICAgIG15c28gPC0gUnVuVU1BUChteXNvLCByZWR1Y3Rpb24gPSBteXBjYSwgZGltcyA9IDE6NTAscmVkdWN0aW9uLm5hbWUgPSBteXVtYXApCiAgICBteXBsb3QgPC0gRGltUGxvdChteXNvLCByZWR1Y3Rpb24gPSBteXVtYXApCiAgICBwbG90KG15cGxvdCArIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9IG15cnVuLCBzdWJ0aXRsZSA9IG15cmVncmVzcykpCiAgfQogIGV4cHRzLmxzW1tteXJ1bl1dIDwtIG15c28KfQpgYGAKCiMjIyBQcmVsaW1pbmFyeSBDbHVzdGVyIElECgpgYGB7ciwgInByZWxpbUNsdXN0ZXJJRCIsIGVjaG89RkFMU0V9Cm1hcmtlcnMgPC0gbGlzdChlYXJseSA9IGMoIlNPWDQiKSwKICAgICAgICAgICAgICAgIG1pZCA9IGMoIkNFQlBEIiksCiAgICAgICAgICAgICAgICBsYXRlID0gYygiQ0QxNCIpKQoKZm9yIChteXJ1biBpbiBydW5zMnByb2Nlc3MpIHsKICBteXNvIDwtIGV4cHRzLmxzW1tteXJ1bl1dCiAgCiAgZm9yIChteW1hcmtlcnMgaW4gbmFtZXMobWFya2VycykpIHsKICAgIG15cGxvdCA8LSBGZWF0dXJlUGxvdChteXNvLCBmZWF0dXJlcyA9IG1hcmtlcnNbW215bWFya2Vyc11dLCBsYWJlbCA9IFRSVUUsIGxhYmVsLnNpemUgPSA1KQogICAgcGxvdChteXBsb3QgKyBwbG90X2Fubm90YXRpb24odGl0bGUgPSBteXJ1biwgc3VidGl0bGUgPSBteW1hcmtlcnMpKQogIH0KfQoKIyBBc3NpZ24gbGFiZWxzIHRvIERNU08KIyBDbHVzdGVyIExhYmVscwpMYWJlbHMubHMgPC0gbGlzdChkbXNvID0gYyhTQ1QuRGlmZl8wID0gImVhcmx5XzEiLCBTQ1QuRGlmZl8xID0gImxhdGVfMiIsIFNDVC5EaWZmXzIgPSAibWlkXzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBTQ1QuRGlmZl8zID0gImxvbmVfMiIsIFNDVC5EaWZmXzQgPSAibG9uZV8zIiwgU0NULkRpZmZfNSA9ICJsYXRlXzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBTQ1QuRGlmZl82ID0gImxvbmVfMSIsIFNDVC5EaWZmXzcgPSAibG9uZV80IiksCiAgICAgICAgICAgICAgICAgIGF2YSA9IGMoU0NULkRpZmZfMCA9ICJsYXRlXzIiLCBTQ1QuRGlmZl8xID0gImVhcmx5XzEiLCBTQ1QuRGlmZl8yID0gIm1pZF8xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBTQ1QuRGlmZl8zID0gImVhcmx5XzIiLCBTQ1QuRGlmZl80ID0gImxvbmVfMiIsIFNDVC5EaWZmXzUgPSAibGF0ZV8xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBTQ1QuRGlmZl82ID0gImxvbmVfNSIsIFNDVC5EaWZmXzcgPSAibG9uZV8xIiwgU0NULkRpZmZfOCA9ICJsb25lXzMiLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNDVC5EaWZmXzkgPSAibG9uZV80IiksCiAgICAgICAgICAgICAgICAgIG9yeSA9IGMoU0NULkRpZmZfMCA9ICJsYXRlXzEiLCBTQ1QuRGlmZl8xID0gImVhcmx5XzEiLCBTQ1QuRGlmZl8yID0gImVhcmx5XzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNDVC5EaWZmXzMgPSAibWlkXzEiLCBTQ1QuRGlmZl80ID0gIm1pZF8yIiwgU0NULkRpZmZfNSA9ICJsYXRlXzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNDVC5EaWZmXzYgPSAibG9uZV8xIiwgU0NULkRpZmZfNyA9ICJsb25lXzMiLCBTQ1QuRGlmZl84ID0gImxvbmVfMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgU0NULkRpZmZfOSA9ICJsb25lXzQiLCBTQ1QuRGlmZl8xMCA9ICJsb25lXzUiKSwKICAgICAgICAgICAgICAgICAgY29tYm8gPSBjKFNDVC5EaWZmXzAgPSAiZWFybHlfMSIsIFNDVC5EaWZmXzEgPSAibGF0ZV8yIiwgU0NULkRpZmZfMiA9ICJtaWRfMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ1QuRGlmZl8zID0gImxhdGVfMSIsIFNDVC5EaWZmXzQgPSAiZWFybHlfMiIsIFNDVC5EaWZmXzUgPSAibG9uZV8xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDVC5EaWZmXzYgPSAibG9uZV8yIiwgU0NULkRpZmZfNyA9ICJsb25lXzMiLCBTQ1QuRGlmZl84ID0gImxvbmVfNCIpKQpsYWJlbF9vcmRlciA8LSBjKCJlYXJseV8xIiwgImVhcmx5XzIiLCAibWlkXzEiLCAibWlkXzIiLCAibGF0ZV8xIiwgImxhdGVfMiIsCiAgICAgICAgICAgICAgICAgImxvbmVfMSIsICJsb25lXzIiLCAibG9uZV8zIiwgImxvbmVfNCIsICJsb25lXzUiKQoKIyBSZW5hbWUgQ2x1c3RlcnMgCiMgVGhpcyBjb3VsZCBiZSBtb3JlIGVsZWdhbnQuLi4gIEknbSBtYWtpbmcgbG90cyBvZiBhc3N1bXB0aW9ucwpjb2xvcnMgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScsJyNmZmZmOTknLCcjYjE1OTI4JykKbmFtZXMoY29sb3JzKSA8LSBsYWJlbF9vcmRlcgoKZm9yIChteXJlZ3Jlc3MgaW4gcmVncmVzc2lvbjJ1c2UpIHsKICBmb3IgKG15cnVuIGluIHJ1bnMycHJvY2VzcykgewogICAgbXlzbyA8LSBleHB0cy5sc1tbbXlydW5dXQogICAgbXlub3JtIDwtIGdzdWIoInJlZ3Jlc3MiLCAiU0NUIiwgbXlyZWdyZXNzKQogICAgCiAgICAjIENyZWF0ZSBhIG5hbWVkIGNvbHVtbgogICAgbXlJZHhuYW1lIDwtIHBhc3RlKG15bm9ybSwgImNsdXN0ZXJJZHgiLCBzZXAgPSAiXyIpCiAgICBteXNvQG1ldGEuZGF0YVtbbXlJZHhuYW1lXV0gPC0gcGFzdGUobXlub3JtLCBteXNvQG1ldGEuZGF0YSRTQ1QuRGlmZl9zbm5fcmVzLjAuOCwgc2VwID0gIl8iKQogICAgCiAgICAjIENyZWF0ZSBhIGxhYmVsZWQgY29sdW1uIChtYWtlIGl0IGEgZmFjdG9yIGZvciBlYXNlIG9mIHJlYWRpbmcpCiAgICBteUlEbmFtZSA8LSBwYXN0ZShteW5vcm0sICJjbHVzdGVySUQiLCBzZXAgPSAiXyIpCiAgICBteXNvQG1ldGEuZGF0YVtbbXlJRG5hbWVdXSA8LSBmYWN0b3IoTGFiZWxzLmxzW1tteXJ1bl1dW215c29AbWV0YS5kYXRhW1tteUlkeG5hbWVdXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGxhYmVsX29yZGVyLCBvcmRlcmVkID0gVFJVRSkKICAgIAogICAgcGxvdGNvbG9ycyA8LSBjb2xvcnNbdW5pcXVlKGxldmVscyhteXNvQG1ldGEuZGF0YVtbbXlJRG5hbWVdXSkpXQogICAgbXlwbG90IDwtIERpbVBsb3QobXlzbywgcmVkdWN0aW9uID0gbXl1bWFwLCBncm91cC5ieSA9IG15SURuYW1lLCBjb2xzID0gcGxvdGNvbG9ycykKICAgIHBsb3QobXlwbG90ICsgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gbXlydW4sIHN1YnRpdGxlID0gbXlub3JtKSkKICAgIAogICAgZXhwdHMubHNbW215cnVuXV0gPC0gbXlzbwogIH0KfQpgYGAKCiMjIyBJbnRlZ3JhdGUgdGhlIG9iamVjdHMKUHJlc2VydmUgYXMgbWFueSBmZWF0dXJlcyBhcyBwb3NzaWJsZSBpbiB0aGUgaW50ZWdyYXRlZCBvYmplY3QKCmBgYHtyLCAiaW50ZWdyYXRlIiwgZWNobz1GQUxTRX0KIyBOZWVkZWQgdG8gYXZvaWQgZXJyb3IgaW4gZ2V0R2xvYmFsc2FuZFBhY2thZ2VzIApvcHRpb25zKGZ1dHVyZS5nbG9iYWxzLm1heFNpemU9IDM1MzAqMTAyNF4yKQoKIyBDb3VudCB0aGUgbnVtYmVyIG9mIHVuaXF1ZSBmZWF0dXJlcyBwZXIgZXhwZXJpbWVudAphbGxGZWF0dXJlcyA8LSBOVUxMCmZvciAobXlydW4gaW4gbmFtZXMoZXhwdHMubHMpKSB7CiAgYWxsRmVhdHVyZXMgPC0gdW5pcXVlKGMoYWxsRmVhdHVyZXMsIHJvd25hbWVzKGV4cHRzLmxzW1tteXJ1bl1dKSkpCn0KCmV4cHRzLmludGVncmF0ZWQubHMgPC0gbGlzdCgpCmZvciAobXlyZWdyZXNzIGluIHJlZ3Jlc3Npb24ydXNlKSB7CiAgIyBTZWxlY3QgbW9zdCB2YXJpYWJsZSBmZWF0dXJlcyBmb3IgaW50ZWdyYXRpb24KICBteWFzc2F5IDwtIGdzdWIoInJlZ3Jlc3MiLCAiU0NUIiwgbXlyZWdyZXNzKQogIG15ZmVhdHVyZXMgPC0gU2VsZWN0SW50ZWdyYXRpb25GZWF0dXJlcyhvYmplY3QubGlzdCA9IGV4cHRzLmxzLCBuZmVhdHVyZXMgPSBsZW5ndGgoYWxsRmVhdHVyZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdmYubmZlYXR1cmVzID0gYWxsRmVhdHVyZXMsIGFzc2F5ID0gcmVwKG15YXNzYXksIDQpKQogIAogICMgQ2FsY3VsYXRlIFBlYXJzb24gUmVzaWR1YWxzCiAgbXlpc28gPC0gUHJlcFNDVEludGVncmF0aW9uKG9iamVjdC5saXN0ID0gZXhwdHMubHMsIGFuY2hvci5mZWF0dXJlcyA9IG15ZmVhdHVyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgYXNzYXkgPSByZXAobXlhc3NheSwgNCkpCiAgCiAgIyBJZGVudGlmeSBpbnRlZ3JhdGlvbiBhbmNob3JzCiAgcmVmIDwtIHdoaWNoKG5hbWVzKGV4cHRzLmxzKSA9PSBiYXNlbGluZSkKICBteS5hbmNob3JzIDwtIEZpbmRJbnRlZ3JhdGlvbkFuY2hvcnMob2JqZWN0Lmxpc3QgPSBteWlzbywgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiU0NUIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSByZXAobXlhc3NheSwgNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZSA9IHJlZiwgc2NhbGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yLmZlYXR1cmVzID0gbXlmZWF0dXJlcywgdmVyYm9zZSA9IFRSVUUpCiAgCiAgIyBJbnRlZ3JhdGUgc2VsZWN0ZWQgZGF0YQogIGludGVncmF0ZWROYW1lIDwtIHBhc3RlKCJJbnRlZ3JhdGVkIiwgbXlhc3NheSwgc2VwID0gIi4iKQogIG15aW50ZWdyYXRlZCA8LSBJbnRlZ3JhdGVEYXRhKGFuY2hvcnNldCA9IG15LmFuY2hvcnMsIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIlNDVCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCBuZXcuYXNzYXkubmFtZSA9IGludGVncmF0ZWROYW1lKQogIAogIGV4cHRzLmludGVncmF0ZWQubHNbW215cmVncmVzc11dIDwtIG15aW50ZWdyYXRlZAp9CmBgYAoKIyMjIE9wdGlvbmFsbHkgUGxvdCBNaXNzaW5nIEZlYXR1cmVzCkxvc2UgfjI1MDAgZmVhdHVyZXMgKG9mIDE2OTkwKSBkdXJpbmcgaW50ZWdyYXRpb24KCmBgYHtyLCAicGxvdG1pc3NpbmdpbnRlZ3JhdGVkIixlY2hvPUZBTFNFfQppZiAoVFJVRSkgewogIGZvciAobXlyZWdyZXNzIGluIG5hbWVzKGV4cHRzLmludGVncmF0ZWQubHMpKSB7CiAgICBteWlzbyA8LSBleHB0cy5pbnRlZ3JhdGVkLmxzW1tteXJlZ3Jlc3NdXQogICAgbG9zdEZlYXQgPC0gcm93bmFtZXMobXlpc29AYXNzYXlzJFNDVC5EaWZmQGNvdW50cylbIShyb3duYW1lcyhteWlzb0Bhc3NheXMkU0NULkRpZmZAY291bnRzKSAlaW4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvd25hbWVzKG15aXNvQGFzc2F5cyRJbnRlZ3JhdGVkLlNDVC5EaWZmQGRhdGEpKV0KICAgIAogICAgY291bnRzLnBlci5mZWF0IDwtIGFwcGx5KG15aXNvQGFzc2F5cyRTQ1QuRGlmZkBjb3VudHMsIDEsIHN1bSkKICAgIGNlbGxzLnBlci5mZWF0IDwtIE1hdHJpeDo6cm93U3VtcyhteWlzb0Bhc3NheXMkU0NULkRpZmZAY291bnRzID4gMCkKICAgIAogICAgIyBQbG90IGNvdW50cyBhbmQgY2VsbHMgCiAgICBwbG90KHggPSBsb2cyKGNvdW50cy5wZXIuZmVhdCksIHkgPSBsb2cyKGNlbGxzLnBlci5mZWF0KSwgcGNoID0gMjAsIGNleCA9IDAuNSwKICAgICAgICAgeGxpbSA9IGMoMCwgMjUpLCB5bGltID0gYygyLCAxNCkpCiAgICBwb2ludHMoeCA9IGxvZzIoY291bnRzLnBlci5mZWF0W2xvc3RGZWF0XSksIHkgPSBsb2cyKGNlbGxzLnBlci5mZWF0W2xvc3RGZWF0XSksIHBjaCA9IDIwLCBjZXggPSAwLjUsIGNvbCA9ICJyZWQiKQogICAgCiAgICBwbG90KHggPSBsb2cyKGNvdW50cy5wZXIuZmVhdFtsb3N0RmVhdF0pLCB5ID0gbG9nMihjZWxscy5wZXIuZmVhdFtsb3N0RmVhdF0pLCBwY2ggPSAyMCwgY2V4ID0gMC41LCBjb2wgPSAicmVkIiwKICAgICAgICAgeGxpbSA9IGMoMCwgMjUpLCB5bGltID0gYygyLCAxNCkpCiAgICBwb2ludHMoeCA9IGxvZzIoY291bnRzLnBlci5mZWF0WyEobmFtZXMoY291bnRzLnBlci5mZWF0KSAlaW4lIGxvc3RGZWF0KV0pLAogICAgICAgICB5ID0gbG9nMihjZWxscy5wZXIuZmVhdClbIShuYW1lcyhjZWxscy5wZXIuZmVhdCkgJWluJSBsb3N0RmVhdCldLCBwY2ggPSAyMCwgY2V4ID0gMC41KQogICAgCiAgICBmb3IgKG15ZXhwdCBpbiBydW5zMnByb2Nlc3MpIHsKICAgICAgCiAgICB9CiAgICAKICB9Cn0KYGBgCgojIyMgUGxvdCBVTUFQIGFuZCBQQ0EKCmBgYHtyLCBlY2hvPUZBTFNFfQpmb3IgKG15ZmlsdCBpbiBuYW1lcyhleHB0cy5scykpIHsKICBmb3IgKG15cnVuIGluIG5hbWVzKGV4cHRzLmxzW1tteWZpbHRdXSkpIHsKICAgIGZvciAobXlyZWdyZXNzIGluIG5hbWVzKHJlZ3Jlc3Npb25zKSkgewogICAgICBteWFzc2F5IDwtIGlmZWxzZShteXJlZ3Jlc3MgPT0gIm5vcmVncmVzc2lvbiIsICJTQ1QiLCBnc3ViKCJyZWdyZXNzIiwgIlNDVCIsIG15cmVncmVzcykpCiAgICAgIG15cGNhIDwtIGdzdWIoIlNDVCIsICJwY2EiLCBteWFzc2F5KQogICAgICBwbG90KERpbVBsb3QoZXhwdHMubHNbW215ZmlsdF1dW1tteXJ1bl1dLCByZWR1Y3Rpb24gPSBteXBjYSkgICsgbGFicyh0aXRsZSA9IHNwcmludGYoIiVzOiAlcyIsIG15cnVuLCBteXJlZ3Jlc3MpKSkKICAgIAogICAgICBteXVtYXAgPC0gZ3N1YigiU0NUIiwgInVtYXAiLCBteWFzc2F5KQogICAgICBwbG90KERpbVBsb3QoZXhwdHMubHNbW215ZmlsdF1dW1tteXJ1bl1dLCByZWR1Y3Rpb24gPSBteXVtYXApICArIGxhYnModGl0bGUgPSBzcHJpbnRmKCIlczogJXMiLCBteXJ1biwgbXlyZWdyZXNzKSkpCiAgICB9CiAgfQp9CmBgYAoKIyMjIFNhdmUgdGhlIGRhdGEKCmBgYHtyLCBlY2hvPUZBTFNFfQojIFNhdmUgdGhlIGZpbGUKZm9yIChteWZpbHQgaW4gbmFtZXMoZXhwdHMubHMpKSB7CiAgZmlsZTJzYXZlIDwtIHNwcmludGYoImFtbF9ldG8ucmVncmVzc1NPLiVzLiVzLnJkcyIsIG15ZmlsdCwgU3lzLkRhdGUoKSkKICBwcmludChzcHJpbnRmKCIlcyBvYmplY3RzOiAgU2F2aW5nIHNjYWxlZC9ub3JtYWxpemVkL3JlZ3Jlc3NlZCBkYXRhIGluIGluZGl2aWR1YWwgb2JqZWN0cyBpbiAlcyIsIG15ZmlsdCwgZmlsZTJzYXZlKSkKICBzYXZlUkRTKGV4cHRzLmxzW1tteWZpbHRdXSwgZmlsZSA9IHBhc3RlKGRpcmVjdG9yeSRyZGEsIGZpbGUyc2F2ZSwgc2VwID0gIi8iKSkKfQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQpzZXNzaW9uSW5mbygpCmBgYAo=